<template>
  <div>
    <!-- 面包屑导航区 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>权限管理</el-breadcrumb-item>
      <el-breadcrumb-item>角色列表</el-breadcrumb-item>
    </el-breadcrumb>

    <!-- 卡片区 -->
    <el-card>
      <!-- 添加角色按钮区域 -->
      <el-row>
        <el-col>
          <el-button type="primary" @click="showAddRoles">添加角色</el-button>
        </el-col>
      </el-row>
      <!-- 角色列表区域 -->
      <el-table :data="rolesList" border stripe row-key="id">
        <!-- 展开列，用来显示 当前角色的 三级角色 -->
        <el-table-column type="expand">
          <template slot-scope="scope">
            <el-row :class="['bdbottom',id1==0?'bdtop':'']" v-for="(item1,id1) in scope.row.children" :key="item1.id" class="vcenter">
              <!-- 一级管理权限 -->
              <el-col :span="5">
                <el-tag closable @close="delRightById(scope.row,item1.id)">
                  {{item1.authName}}
                </el-tag>
                <i class="el-icon-caret-right"></i>
              </el-col>
              <!-- 二级和三级权限 -->
              <el-col :span="19">
                <!-- 循环嵌套二级权限 -->
                <el-row :class="[id2==0?'':'bdtop']" v-for="(item2,id2) in item1.children" :key="item2.id" class="vcenter">
                  <el-col :span="6">
                  <el-tag  type="danger" closable @close="delRightById(scope.row,item2.id)">{{item2.authName}}</el-tag> <i class="el-icon-caret-right"></i>
              </el-col>
                  <!-- 循环嵌套三级权限 -->
              <el-col :span="18">
                  <el-row >
                      <el-tag v-for="item3 in item2.children" :key="item3.id" type="warning" closable @close="delRightById(scope.row,item3.id)">{{item3.authName}}</el-tag>
                   </el-row>
              </el-col>
                </el-row>
              </el-col>
            </el-row>
          </template>
        </el-table-column>
        <el-table-column type="index" label="#"></el-table-column>
        <el-table-column prop="roleName" label="角色名" ></el-table-column>
        <el-table-column prop="roleDesc" label="说明" ></el-table-column>
        <el-table-column label="操作" >
          <template slot-scope="scope">
            <el-button size="mini" type="primary" icon="el-icon-edit" @click="editRoles(scope.row)">编辑</el-button>
            <el-button size="mini" type="danger" icon="el-icon-delete" @click="delRoles(scope.row.id)">删除</el-button>
            <el-button size="mini" type="warning" icon="el-icon-setting" @click="ShowRightDialog(scope.row)">分配权限</el-button>
          </template>
        </el-table-column>
      </el-table>

       <!-- 分配权限对话框 -->
      <el-dialog title="分配权限" :visible.sync="isShowRightDialog" width="50%" @close="closeRightDialog">
        <!-- 树形菜单 -->
        <el-tree :data="rightsList" :props="rightProps" show-checkbox  ref="rightTree"
        default-expand-all node-key="id" :default-checked-keys="checkedKeys" > </el-tree>
        <span slot="footer" class="dialog-footer">
          <el-button @click="isShowRightDialog = false">取 消</el-button>
          <el-button type="primary" @click="setRoleRihgts" >确 定</el-button>
        </span>
      </el-dialog>

      <!-- 添加角色的对话框 -->
      <el-dialog title="添加角色"  :visible.sync="isShowAddtDialog" width="50%" @close="closeAddDialog">
        <el-form ref="addFormRef" :rules="addFormRules" :model="addForm" label-width="80px">
          <el-form-item label="角色名：" prop="roleName">
            <el-input v-model="addForm.roleName"></el-input>
          </el-form-item>
          <el-form-item label="说明：" prop="roleDesc">
            <el-input v-model="addForm.roleDesc"></el-input>
          </el-form-item>
        </el-form>
        <span slot="footer" class="dialog-footer">
          <el-button @click="isShowAddtDialog = false">取 消</el-button>
          <el-button type="primary" @click="setAddRoles" >确 定</el-button>
        </span>
      </el-dialog>

       <!-- 编辑角色的对话框 -->
      <el-dialog title="添加角色"  :visible.sync="isShowEdittDialog" width="50%" @close="closeEditDialog">
        <el-form ref="editFormRef" :rules="editFormRules" :model="editForm" label-width="80px">
          <el-form-item label="角色名：" prop="roleName">
            <el-input v-model="editForm.roleName"></el-input>
          </el-form-item>
          <el-form-item label="说明：" prop="roleDesc">
            <el-input v-model="editForm.roleDesc"></el-input>
          </el-form-item>
        </el-form>
        <span slot="footer" class="dialog-footer">
          <el-button @click="isShowEdittDialog = false">取 消</el-button>
          <el-button type="primary" @click="setEditRoles" >确 定</el-button>
        </span>
      </el-dialog>
    </el-card>
  </div>
</template>
<script>
export default {
  data () {
    return {
      roleId: [],
      // 角色列表
      rolesList: [],
      // dialog 对话框的属性
      isShowRightDialog: false,
      isShowAddtDialog: false,
      isShowEdittDialog: false,
      rightsList: [],
      addForm: {
        roleName: '',
        roleDesc: ''
      },
      editForm: {
        id: '',
        roleName: '',
        roleDesc: ''
      },
      addFormRules: {
        roleName: [{ required: true, message: '请输入角色名', trigger: 'blur' }],
        roleDesc: [{ required: true, message: '请输入说明', trigger: 'blur' }]
      },
      editFormRules: {
        roleName: [{ required: true, message: '请输入角色名', trigger: 'blur' }],
        roleDesc: [{ required: true, message: '请输入说明', trigger: 'blur' }]
      },
      // 树形菜单的配置对象
      rightProps: {
        label: 'authName',
        children: 'children'
      },
      checkedKeys: []
    }
  },
  created () {
    // 调用方法，获取角色列表
    this.getRolesList()
  },
  methods: {
    // 编辑角色
    editRoles (row) {
      this.editForm.roleName = row.roleName
      this.editForm.roleDesc = row.roleDesc
      this.isShowEdittDialog = true
      this.editForm.id = row.id
    },
    // 关闭编辑对话框
    closeEditDialog () {
      // 将表单清空
      this.$refs.editFormRef.resetFields()
      // 关闭 编辑对话框
      this.isShowEdittDialog = false
    },
    // 设置编辑对话框
    setEditRoles () {
      // 获取文本框中的数据，方便一会发起请求
      const editParams = {
        roleName: this.editForm.roleName,
        roleDesc: this.editForm.roleDesc
      }
      // 验证表单
      this.$refs.editFormRef.validate(async (valid) => {
        if (!valid) return
        // 如果表单验证成功，发起编辑请求
        const { data: res } = await this.$http.put(`roles/${this.editForm.id}`, editParams)
        if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
        this.$message.success(res.meta.msg)
        // 重新渲染列表
        this.getRolesList()
      })
      this.isShowEdittDialog = false
    },
    // 删除角色
    delRoles (roleId) {
      this.$messageBox.confirm('确认删除?', '系统提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        callback: async (action) => {
          // 如果点击取消按钮，则停止执行函数
          if (action === 'cancel') return
          // 发起请求 删除角色
          const { data: res } = await this.$http.delete(`roles/${roleId}`)
          // 如果删除失败，弹出失败消息
          if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
          // 调用函数重新渲染列表
          this.getRolesList()
        }
      })
    },
    // 显示添加角色的对话框
    showAddRoles () {
      this.isShowAddtDialog = true
    },
    // 添加角色对话框的关闭事件
    closeAddDialog () {
      this.$refs.addFormRef.resetFields()
      this.isShowAddtDialog = false
    },
    // 点击 添加角色
    setAddRoles () {
      // 验证表单 是否符合规则
      this.$refs.addFormRef.validate(async (valid) => {
        if (!valid) return
        // 发起请求添加角色
        const { data: res } = await this.$http.post('roles', this.addForm)
        // 如果添加角色失败，则弹出错误
        if (res.meta.status !== 201) return this.$message.error(res.meta.msg)
        // 添加成功，重新渲染页面
        this.getRolesList()
      })
      this.isShowAddtDialog = false
    },
    // 关闭对话框
    closeRightDialog () {
      this.checkedKeys = []
    },
    // 确定分配 角色 权限 按钮点击事件方法
    async setRoleRihgts () {
      // 可以通过 this.roleId 获取 当前要需要修改权限的 id
      // 获取 选中的 权限 id  并转成 分隔的字符串
      const a = this.$refs.rightTree.getCheckedKeys()
      const b = this.$refs.rightTree.getHalfCheckedKeys()
      // 将获取的全选 和 半选的 权限的  id 组成一个 新数组
      const rightsIds = [...a, ...b]
      // 将新的权限的 id  以 , 分隔的方式组成一个字符串
      const strIds = rightsIds.join(',')
      // 发送请求 到 服务器接口，更新角色权限
      const { data: res } = await this.$http.post(`roles/${this.roleId}/rights`, { rids: strIds })
      // 如果请求失败，则提示
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      // 如果请求成功，则重新请求 整个 角色视图数据
      this.$message.success(res.meta.msg)
      // 关闭当前对话框
      this.isShowRightDialog = false
    },
    // 分配权限 id
    getRightId (rightsList) {
      rightsList.forEach((ele) => {
        if (ele.children) {
          this.getRightId(ele.children)
        } else {
          this.checkedKeys.push(ele.id)
        }
      })
    },
    // 点击 弹出分配权限对话框
    async ShowRightDialog (rowData) {
      // 将角色Id 保存到 data 中，等点击确认分配权限时
      this.roleId = rowData.id
      // 将 isShowRightDialog 改为 true 显示出对话框
      this.isShowRightDialog = true
      // 发生请求，获取所有的权限列表
      const { data: res } = await this.$http.get('rights/tree')
      if (res.meta.status !== 200) return this.$message.error('获取权限列表失败')
      // 将获取的数据赋值给权限列表
      this.rightsList = res.data
      // 将当前角色 拥有的权限 设置为 选中状态
      // 将 当前角色 一级权限 数组 传入
      this.getRightId(rowData.children)
    },
    // 创建函数，获取数据
    async getRolesList () {
      // 发起请求
      const { data: res } = await this.$http.get('roles')
      // 如果获取数据失败，则弹出错误
      if (res.meta.status !== 200) return this.$message.error('获取角色列表失败！')
      // 如果获取成功 将获取的数据赋值给 角色列表
      this.rolesList = res.data
    },
    // 删除权限函数
    delRightById (roleData, rightId) {
      this.$messageBox.confirm('确认删除?', '系统提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        callback: async (action) => {
          // 如果点击取消按钮，则停止执行函数
          if (action === 'cancel') return
          // 如果点击确认按钮，根据id 请求，服务器删除权限接口
          const { data: res } = await this.$http.delete(`roles/${roleData.id}/rights/${rightId}`)
          // 如果删除失败，弹出提示
          if (res.meta.status !== 200) return this.$message.error('删除权限失败')
          this.$message.success('删除权限成功')
          // 如果删除成功，则 更新视图 中的 角色权限
          // 将 当前行数据的权限数组 换成接口返回的 新的权限数组
          // 由于数组发生改变 所以视图 会重新渲染这个角色的权限列表
          roleData.children = res.data
        }
      })
    }

  }
}
</script>
<style lang="less" scoped>
.el-tag{
  margin: 7px;
}
.bdtop{
  border-top: 1px solid #eee;
}
.bdbottom{
  border-bottom: 1px solid #eee;
}
.vcenter{
  display: flex;
  align-items: center;
}
.el-table{
  margin-top: 15px;
}
</style>
